require_relative 'algorithms/recursive_backtracker'

module Maze
  GENERATORS = { :text => { :orthogonal => Maze::TextFormatter::Orthogonal,
                            :sigma      => Maze::TextFormatter::Sigma },
                 :png  => { :orthogonal => Maze::PngFormatter::Orthogonal,
                            :sigma      => Maze::PngFormatter::Sigma } }

  class Generic

    attr_reader :width, :height, :grid, :algorithm

    N  = :north
    S  = :south
    E  = :east
    W  = :west
    NE = :north_east
    NW = :north_west
    SE = :south_east
    SW = :south_west

    def initialize(params)
      @width     = params.fetch(:width,  10)
      @height    = params.fetch(:height, 10)
      @grid      = Array.new(height) { Array.new(width) }
      @algorithm = Algorithm::RecursiveBacktracker.new(self)
    end

    def generate
      tap { algorithm.run }
    end

    def connected?(point, direction)
      self[point].include?(direction)
    end

    def connect(current_point, next_point, direction)
      self[current_point] = direction
      self[next_point]    = opposite(direction)
    end

    def []=(point, direction)
      grid[point.y][point.x] ||= []
      grid[point.y][point.x] << direction
    end

    def [](point)
      grid[point.y][point.x]
    end

    def draw(format, output_file = nil)
      generator = GENERATORS[format][tessellation].new(self)
      output_file ? generator.draw(output_file) : generator.draw
    end

    def tessellation
      self.class.name[/::(.*)$/, 1].downcase.to_sym
    end

  end
end
